﻿using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Text;
using System.Windows.Data;
using System.Collections.ObjectModel;
using System.Threading;
using System.Activities.Presentation.Toolbox;

namespace MultipleAppDomainTest
{
    /// <summary>
    /// Part of the View layer, creates ToolboxControls wrapped by ToolboxWrappers.
    /// </summary>
    [ValueConversion(typeof(ObservableCollection<ActivityAssemblyItem>), typeof(ObservableCollection<ToolboxControl>))]
    public class ActivityAssemblyItemsToToolboxWrappersConverter : IValueConverter
    {
        /// <summary>
        /// Convert an ObservableCollection of ActivityAssemblyItems into an ObservableCollection of ToolboxWrappers
        /// and link them so that inserting/deleting ActivityAssemblyItems regenerates the ToolboxWrapper collection.
        /// </summary>
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            Contract.Requires(value is ObservableCollection<ActivityAssemblyItem>);
            var items = (ObservableCollection<ActivityAssemblyItem>)value;
            var controls = new ObservableCollection<ToolboxControl>(new[] { ToolboxControlService.CreateToolboxes(items) });
            // When someone adds/changes assemblies, we need to refresh toolbox controls

            var syncContext = SynchronizationContext.Current;
            bool notRefreshedYet;
            items.CollectionChanged += (s, arg) =>
            {
                notRefreshedYet = true;

                // Do refresh asyncronously via Post so we can consolidate multiple notifications into one refresh
                syncContext.Post(callbackInfo =>
                {
                    if (notRefreshedYet)
                    {
                        notRefreshedYet = false;
                        controls.Clear();
                        controls.Add(ToolboxControlService.CreateToolboxes(new ObservableCollection<ActivityAssemblyItem>(items)));
                    }
                },
                null);
            };

            return controls;
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}
